/*
 * Demonstrates the moving versions of std::accumulate et al, 
 * introduced in C++20.
 * 
 * To avoid issues with the names being overloaded, they are 
 * offered in two ways:
 * 
 * a) under namespace cxxomfort::cxxostd::cxx20
 * b) with tail argument of type "numeric_move_tag"
 * 
 * */
#include <cxxomfort/base.hpp>
#include <cxxomfort/algorithm.hpp>
#include <cxxomfort/numeric.hpp>
#include <cxxomfort/type_traits.hpp>
#include <cxxomfort/string.hpp>
#include <cassert>
#include <cstddef> // std::byte
#include <vector>
#include <iostream>
#include <ctime>

const unsigned CALLS=10;

int main () {
	using namespace std;
	vector<string> V(2000);
	for(unsigned i=0; i < V.size(); ++i) {
		V[i]= to_string(i+1) + "*";
	}
	string scopy;
	clock_t timec[2] = {clock(), 0 };
	for (unsigned t= 0; t<CALLS; ++t) {
		using std::accumulate;
		scopy= accumulate(begin(V), end(V), string() );
	}
	timec[1]= clock();
	//cout<< scopy<< endl;
	cout<< "normal std version : "<< (timec[1] - timec[0])<< endl;
	cout<< endl;
	
	// access to move versions
	// a) via a tag argument, "numeric_move_tag"
	clock_t time_numtag[2] = {clock(), 0 };
	
	for (unsigned t= 0; t<CALLS; ++t) {
		using namespace cxxomfort::fix;
		//using cxxomfort::fix::numeric_move_tag;
		//using cxxomfort::fix::accumulate;
		scopy= accumulate(begin(V), end(V), string(), numeric_move_tag());
	}
	time_numtag[1]= clock();
	cout<< "cxxo with numeric_move_tag : "<< (time_numtag[1] - time_numtag[0])<< endl;
	cout<< endl;

	// access to move versions
	// b) via qualified name
	clock_t timens[2] = {clock(), 0 };
	for (unsigned t= 0; t<CALLS; ++t) {
		scopy= cxxomfort::cxxostd::numeric20::accumulate(begin(V), end(V), string() );
	}
	timens[1]= clock();
	cout<< "cxxo with numeric20:: : "<< (timens[1] - timens[0])<< endl;
	cout<< endl;

#if 0
	// access to move versions
	// c) via a different name
	clock_t timedi[2] = {clock(), 0 };
	for (unsigned t= 0; t<CALLS; ++t) {
		using cxxomfort::fix::move_accumulate;
		scopy= cxxomfort::fix::move_accumulate(begin(V), end(V), string() );
	}
	timedi[1]= clock();
	cout<< "cxxo with numeric20:: : "<< (timedi[1] - timedi[0])<< endl;
	cout<< endl;

#endif
}
